<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/6/20 0020
 * Time: 上午 11:45
 */
namespace app\api\service;

use app\common\DictConstant;
use app\common\model\Integralrecord;
use app\common\model\Product;
use app\common\BaseHelper;
use app\common\model\Orderproductdetail;
use app\common\model\Productspecgroups;
use app\common\model\User;
use app\lib\exception\OrderException;
use app\lib\exception\ParameterException;
use think\Db;
use think\Exception;


class IntegralOrder{
    //订单商品列表，也就是客户端传过来的products
    protected $oProducts;

    //真实的商品信息，从数据库查出来的（包括库存量）
    protected $products;
    protected $uid;
    protected $tenantid;
    protected $storeid;
    protected $ordertype;
    protected $deliverAddress = NULL;
    protected $userName = NULL;
    protected $userPhone = NULL;
    protected $subscribeDate = NULL;
    protected $content = NULL;
    protected $freight = 0;
    protected $packingfee = 0;
    protected $linkType = DictConstant::ORDER_LINK_TYPE_2;

    /**
     * 创建积分订单入口
     * @param $uid
     * @param $orderdata
     * @param $oProducts
     * @return array
     * @throws ParameterException
     */
    public function place($uid,$orderdata,$oProducts){
        //oProducts和products进行对比
        $this->oProducts = $oProducts;
        $this->products = $this->getProductsByOrder($oProducts);
        $this->uid = $uid;
        $this->tenantid = $orderdata['tenantid'];
        $this->storeid = isset($orderdata['storeId'])?$orderdata['storeId']:null;
        $this->ordertype = $orderdata['orderType'];
        $this->content = isset($orderdata['content'])?$orderdata['content']:null;
        $this->freight = isset($orderdata['freight'])?$orderdata['freight']:0;
        $this->packingfee = isset($orderdata['packingfee'])?$orderdata['packingfee']:0;
        if($orderdata['orderType'] == DictConstant::ORDER_TYPE_ONLINE){
            if($this->ischeckaddress($orderdata)){
                $this->deliverAddress = $orderdata['deliverAddress'];
                $this->userName = $orderdata['userName'];
                $this->userPhone = $orderdata['userPhone'];
            }else{
                throw new ParameterException([
                    'msg' => '用户收货信息异常！',
                ]);
            }
        }else{
            if(isset($orderdata['subscribeDate']) && !empty($orderdata['subscribeDate'])){
                $this->subscribeDate = $orderdata['subscribeDate'];
            }else{
                throw new ParameterException([
                    'msg' => '预约时间异常！'
                ]);
            }
        }

        $status = $this->getOrderStatus();

        if(!$status['pass']){
            $status['order_id'] = -1;
            $status['message'] = '库存不足';
            return $status;
        }


//        //运费
//        if($this->freight){
//            $status['orderPrice'] += $this->freight;
//        }
//        //包装费
//        if($this->packingfee){
//            $status['orderPrice'] += $this->packingfee;
//        }

        //开始创建订单
        $orderSnap = $this->snapOrder($status);

        $order = $this->createOrder($orderSnap);
        //开始付款（扣积分）
        //1.判断用户积分是否够用 2.减用户积分 3.修改订单状态 4.记录积分明细
        return $this->IntegralPay($order);


    }

    private function IntegralPay($order){
        Db::startTrans();
        try{
            if(isset($order['orderNO']) && !empty($order['orderNO'])){
                $uid = $order['uid'];
                $user = User::get($uid);
                if($user->integral<$order['total']){
                    throw new ParameterException([
                        'msg' => '您的积分不够啦'
                    ]);
                }
                User::where('id',$uid)->setDec('integral',$order['total']);
                $order = \app\common\model\Order::get($order['orderId']);
                $order->status = DictConstant::OrderPendingDelivery;
                $order->payDate = date('Y-m-d H:i:s',time());
                $order->save();

               $Integralrecord = new Integralrecord();
               $Integralrecord->id = BaseHelper::getUUID();
               $Integralrecord->type = 1;
               $Integralrecord->integral = $order['total'];
               $Integralrecord->orderId = $order->id;
               $Integralrecord->orderPrice = $order->total;
               $Integralrecord->userId = $order->createUser;
               $Integralrecord->tenantId = $order->tenantId;
               $Integralrecord->save();


            }else{
                throw new ParameterException([
                    'msg' => '积分订单创建失败'
                ]);
            }
            Db::commit();
            return [
                'pass' => true,
            ];
        }catch (Exception $ex){
            Db::rollback();
            return [
                'pass' => false,
                'message' => $ex->msg
            ];
        }
    }

    private function ischeckaddress($orderdata){
        if(isset($orderdata['deliverAddress']) && !empty($orderdata['deliverAddress']) && isset($orderdata['userName']) && !empty($orderdata['userName']) && isset($orderdata['userPhone']) && !empty($orderdata['userPhone'])){
            return true;
        }else{
            return false;
        }
    }


    //创建订单
    private function createOrder($orderSnap){
        Db::startTrans();
        try
        {
            $orderNo = Order::makeOrderNo();
            $order = new \app\common\model\Order();
            $order->id = BaseHelper::getUUID();
            $order->createUser = $this->uid;
            $order->tenantId = $this->tenantid;
            $order->storeId = $this->storeid;
            $order->content = $this->content;
            $order->deliverAddress = $this->deliverAddress;
            $order->userName = $this->userName;
            $order->userPhone = $this->userPhone;
            $order->subscribeDate = $this->subscribeDate;
            $order->type = $this->ordertype;
            $order->orderNO = $orderNo;
            $order->total = $orderSnap['integralPrice'];
            $order->freight = $this->freight;
            $order->packingfee = $this->packingfee;
            $order->total_count = $orderSnap['totalCount'];
            $order->userAddressId = $orderSnap['snapAddressId'];
            $order->linkType = $this->linkType;
            $order->save();

            $orderId = $order->id;
            $create_time = $order->create_time;
            $i = 0;
            foreach ($this->oProducts as &$p)
            {
                $p['id'] = BaseHelper::getUUID();
                $p['orderId'] = $orderId;
                $p['productName'] = $orderSnap['pStatus'][$i]['title'];
                $p['productImg'] =  $orderSnap['pStatus'][$i]['imgUrl'];
                $p['specid'] =  isset($orderSnap['pStatus'][$i]['specid'])?$orderSnap['pStatus'][$i]['specid']:null;
                $p['productSpec'] =  isset($orderSnap['pStatus'][$i]['specDetails1'])?$orderSnap['pStatus'][$i]['specDetails1']:null;
                $p['productSpec1'] =  isset($orderSnap['pStatus'][$i]['specDetails2'])?$orderSnap['pStatus'][$i]['specDetails2']:null;
                $p['productSpec2'] =  isset($orderSnap['pStatus'][$i]['specDetails3'])?$orderSnap['pStatus'][$i]['specDetails3']:null;
                $p['price'] = $orderSnap['pStatus'][$i]['currentPrice'];
                $p['userId'] = $this->uid;
                $p['tenantId'] = $this->tenantid;
                $i++;
            }
            $orderProduct = new Orderproductdetail();
            $orderProduct->saveAll($this->oProducts,false);

            Db::commit();
            return [
                'orderNO' => $orderNo,
                'orderId' => $orderId,
                'create_time' => $create_time,
                'total' => $order->total,
                'uid' => $order->createUser
            ];

        }catch (Exception $e){
            Db::rollback();
            throw $e;
        }
    }


    // 生成订单快照(历史订单信息，不随着商品的变化而变化)
    private function snapOrder($status){
        $snap = [
            'orderPrice' => 0,
            'integralPrice' => 0,
            'totalCount' => 0,
            'pStatus' => [],
            'snapAddressId' => null,
            'snapName' => '',
            'snapImg' => ''
        ];
        $snap['orderPrice'] = $status['orderPrice'];
        $snap['integralPrice'] = $status['integralPrice'];
        $snap['totalCount'] = $status['totalCount'];
        $snap['pStatus'] = $status['pStatusArray'];
        //$snap['snapAddressId'] = $this->getUserAddress();
        $snap['snapName'] = $this->products[0]['title'];
        $snap['snapImg'] = $this->products[0]['imgUrl'];
        if (count($this->products) > 1)
        {
            $snap['snapName'] .= '等';
        }
        return $snap;
    }


    /**
     * 根据订单ID进行库存量检测
     * @param $orderID
     * @return array
     */
    public function checkOrderStock($orderID){
        $oProducts = Orderproductdetail::where('orderId','=',$orderID)->select();
        $this->oProducts = $oProducts;
        $this->products = $this->getProductsByOrder($oProducts);
        $status = $this->getOrderStatus();
        return $status;
    }

    /**
     * 获取订单状态
     * @return array
     */
    private function getOrderStatus(){
        $status = [
            'pass' => true,
            'orderPrice' => 0,
            'integralPrice' => 0,
            'totalCount' => 0,
            'pStatusArray' => []
        ];
        foreach ($this->oProducts as $oProduct){

            $pStatus = $this->getProductStatus($oProduct['productId'],$oProduct['count'],$this->products);


            if(!$pStatus['havestoreCount']){
                $status['pass'] = false;
            }
            $status['orderPrice'] += $pStatus['totalPrice'];
            $status['integralPrice'] += $pStatus['integralPrice'];
            $status['totalCount'] += $pStatus['counts'];
            $status['title'] = $pStatus['title'];
            array_push($status['pStatusArray'], $pStatus);

        }
        return $status;
    }

    /**
     * 获取商品状态 （主要是做库存量检测，发现购物车有一种商品库存量不足，整个订单库存量检测不通过）
     * @param $oPID
     * @param $oCount
     * @param $products
     * @return array
     * @throws OrderException
     */
    private function getProductStatus($oPID,$oCount,$products){
        $pIndex = -1;
        $pStatus = [
            'id' => null,
            'havestoreCount' => false,
            'counts' => 0,
            'currentPrice' => 0,
            'title' => '',
            'totalPrice' => 0,
            'integralPrice' => 0,
            'imgUrl' => null,
            'specDetails1' => null,
            'specDetails2' => null,
            'specDetails3' => null
        ];
        for ($i = 0; $i < count($products); $i++)
        {
            if ($oPID == $products[$i]['id'])
            {
                $pIndex = $i;
            }
        }
        if($pIndex == -1){
            // 客户端传递的productId有可能根本不存在
            throw new OrderException([
                'msg' => 'id为' . $oPID . '的商品不存在，创建订单失败'
            ]);
        }else{
            $product = $products[$pIndex];
            $pStatus['id'] = $product['id'];
            $pStatus['title'] = $product['title'];
            $pStatus['counts'] = $oCount;
            $pStatus['currentPrice'] = $product['currentPrice'];
            $pStatus['imgUrl'] = $product['imgUrl'];
            $pStatus['totalPrice'] = $product['currentPrice'] * $oCount;
            $pStatus['integralPrice'] = $product['integralPrice'] * $oCount;
            if(isset($product['specDetails1']) && !empty($product['specDetails1'])){
                $pStatus['specDetails1'] = $product['specDetails1'];
            }
            if(isset($product['specDetails2']) && !empty($product['specDetails2'])){
                $pStatus['specDetails2'] = $product['specDetails2'];
            }
            if(isset($product['specDetails3']) && !empty($product['specDetails3'])){
                $pStatus['specDetails3'] = $product['specDetails3'];
            }
            if(isset($product['specid']) && !empty($product['specid'])){
                $pStatus['specid'] = $product['specid'];
            }


            if($product['isStore'] == 0){
                $pStatus['havestoreCount'] = true;
            }else{
                if($product['storeCount'] - $oCount >= 0){
                    $pStatus['havestoreCount'] = true;
                }
            }

        }
        return $pStatus;
    }

    /**
     * 根据订单查找真实的商品信息
     * @param $oProducts
     * @return mixed
     */
    private function getProductsByOrder($oProducts){

        $oPIDs = [];
        $specIDS = [];
        if(!is_array($oProducts)){
            throw new ParameterException([
                'msg' => '缺少购买的商品信息'
            ]);
        }
        foreach ($oProducts as $item){
            if(isset($item['specid'])){
                array_push($specIDS,$item['specid']);
            }
            array_push($oPIDs,$item['productId']);
        }
        $products = Product::all($oPIDs)->visible(['id','currentPrice','integralPrice','storeCount','isStore','title','imgUrl','specClass'])->toArray();
        if(count($specIDS)>0){
            $specs = Productspecgroups::all($specIDS)->visible(['id','specDetails1','specDetails2','specDetails3','currentPrice','integralPrice','storeCount','isStore','productId'])->toArray();
            foreach ($products as &$product){
                if($product['specClass']==2){
                    foreach ($specs as $spec){
                        if($spec['productId']==$product['id']){
                            $product['currentPrice'] = $spec['currentPrice'];
                            $product['integralPrice'] = $spec['integralPrice'];
                            $product['specDetails1'] = $spec['specDetails1'];
                            $product['specDetails2'] = $spec['specDetails2'];
                            $product['specDetails3'] = $spec['specDetails3'];
                            $product['storeCount'] = $spec['storeCount'];
                            $product['specid'] = $spec['id'];

                        }
                    }
                }
            }
        }
        return $products;
    }


}